<?php
namespace App\Services\Algo;
use App\Interf\Calculable;
use Encore\Admin\Form\Field\Number;

/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2016/11/24
 * Time: 15:52
 */

class HighBloodPressureAlgo extends BaseTestingAlgo implements Calculable{

    protected  $typeFourExpress;

    public function __construct($tid,$answerStr,$typeFourExpress=null)
    {
        parent::__construct($tid,$answerStr);

        $this->typeFourExpress=$typeFourExpress;
    }

    /**
     * 公共接口
     */
    public function calculate()
    {
        if($this->typeFourExpress){
            $fourTypeResult = $this->fourTypeArray($this->typeFourExpress,$this->answers);
            foreach($fourTypeResult as $v){
                array_push($this->answers,$v);
            }
        }
        return $this->entrance($this->answers);
    }


    /**将拼装后的答案转换成字符串
     * @return string
     */
    public function resultToStr(){
        return $this->arrToStr($this->answers);
    }


    /**返回额外参数
     * @return mixed
     */
    public function getExtraParam(){
        $result = $this->answers;
        return $result[8]['weight'];
    }

    /**
     * 高血压算法入口
     * @param $answer array 答案数组
     * @return Number
     */
    protected function entrance($answers){
        $paramZ = $this->calcuteParamZ($answers);
        $relateAnswer = $this->getRelateIndexAnswer($answers, 9);
        $score = $this->calcProbility($paramZ,$relateAnswer);
        return $score;
    }

    /**
     * 计算概率
     * @param $paramZ Number  参数z
     * @param $relateAnswer array 相关联的答案
     * @return Number;
     */
    protected function calcProbility($paramZ,$relateAnswer){
        $innerP = (log($relateAnswer['weight'])-$paramZ)/0.87692;
        $secondaryP = -exp($innerP);
        $thirdP = 1-exp($secondaryP);
        //计算出来的是两位小数
       $probility = round($thirdP,4)*100;
        $result = $probility;
        return $result;
    }


    /**
     * 获取高血压患病概率关联的序号对应的答案
     * @param $obj array  临时参数数字
     * @param $answer array 答案数组
     * @return Number;
     */
    protected function getRelateIndexAnswer($answers, $index){
        $target = [];
        foreach ($answers as $an){
            if($an['index'] == $index){
                $target = $an;
                break;
            }
        }
        return $target;
    }

    /**
     * 计算参数z
     * Z=-0.202933*@1-0.156412*@2-0.05933*@5-0.128468*@6-0.190731*@7-0.166121*@8-0.033881*@9+0.001624*@10
     * @param $answers array 答案列表
     * @return Number;
     */
    protected function calcuteParamZ($answers){
        $relQuestionIndex = [1,2,5,6,7,8,10,11];
        $data = [];
        foreach ($answers as $answer){
            if(in_array($answer['index'],$relQuestionIndex)){
                $obj['index'] = $answer['index'];
                $answer['index'] = $this->convertCalEffection($obj,$answer);
                array_push($data,$obj);
            }
        }
        $total = 22.949536;
        foreach ($data as $d){
            $total = $total + $d['effection']*$d['operateNum'];
        }
        return $total;
    }



    /**
     * 转换参数P的计算因子
     * @param $obj array  临时参数数字
     * @param $answer array 答案数组
     */
    private function convertCalEffection(&$obj,$answer){
        $effection = 0;
        $midOperate = '*';
        $operateNum = 0;
        $realAnswer = 0;
        switch ($answer['index']){
            case 1 :
                $effection = -0.156412;
                $operateNum = $answer['answer'];
                break;
            case 2 :
                $effection = -0.202933;
                $operateNum = $answer['weight'];
                break;
            case 5 :
                $effection = -0.05933;
                $operateNum = $answer['answer'];
                break;
            case 6 :
                $effection = -0.128468;
                $operateNum = $answer['answer'];
                break;
            case 7 :
                $effection = -0.190731;
                $operateNum = $answer['weight'];
                break;
            case 8 :
                $effection = -0.166121;
                $operateNum = $answer['weight'];
                break;
            case 10 :
                $effection = -0.033881;
                $operateNum = $answer['weight'];
                break;
            case 11 :
                $effection = 0.001624;
                $operateNum = $answer['weight'];
                break;
        }
        $obj['effection'] = $effection;
        $obj['midOperate'] = $midOperate;
        $obj['operateNum'] = $operateNum;
    }

}